package com.xc.hotelmgr.order.modules.ctrip.service;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.xc.hotelmgr.order.common.utils.Constant;
import com.xc.hotelmgr.order.common.utils.DateUtils;
import com.xc.hotelmgr.order.modules.ali.service.DeliGoodsService;
import com.xc.hotelmgr.order.modules.ctrip.sdk.CtripClient;
import com.xc.hotelmgr.order.modules.ctrip.sdk.CtripInterface;
import com.xc.hotelmgr.order.modules.ctrip.sdk.CtripDtInfo;
import com.xc.hotelmgr.order.modules.ctrip.to.detail.request.CtripDetail;
import com.xc.hotelmgr.order.modules.ctrip.to.moniorder.request.CtripMonitor;
import com.xc.hotelmgr.order.modules.ctrip.to.moniorder.request.HotelReservations;
import com.xc.hotelmgr.order.modules.ctrip.to.common.UniqueID;
import com.xc.hotelmgr.order.modules.ctrip.to.moniorder.response.CtripMonitorResponse;
import com.xc.hotelmgr.order.modules.ctrip.to.moniorder.response.HotelReservationIDs;
import com.xc.hotelmgr.order.modules.ctrip.to.moniorder.response.RHotelReservations;
import com.xc.hotelmgr.order.modules.order.entity.DtOrderChannelsEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service("monitOrdStatusService")
public class MonitOrdStatusService {
    @Autowired
    private DeliGoodsService deliGoodsService;

    /**
     * 定时监控携程订单状态变化
     * @param dtOrderChannelsEntity
     */
    @Async
    public void monitOrdStatusAsyncTask(DtOrderChannelsEntity dtOrderChannelsEntity) {
        CtripDtInfo ctripDtInfo = new CtripDtInfo();
        ctripDtInfo.setAID(Integer.valueOf(dtOrderChannelsEntity.getAccessKey()));
        ctripDtInfo.setSID(dtOrderChannelsEntity.getSid());
        ctripDtInfo.setKey(dtOrderChannelsEntity.getSecretKey());
        ctripDtInfo.setAccess_Token(dtOrderChannelsEntity.getAccessToken());
        ctripDtInfo.setUniqueID(dtOrderChannelsEntity.getUniqueId());
        ctripDtInfo.setAccess_Token(dtOrderChannelsEntity.getAccessToken() == null ? "" : dtOrderChannelsEntity.getAccessToken());
        ctripDtInfo.setRefresh_Token(dtOrderChannelsEntity.getRefreshToken() == null ? "" : dtOrderChannelsEntity.getRefreshToken());
        ctripDtInfo.setICODE(CtripInterface.MoniOrderStatus.getValue());
        UniqueID uniqueID = new UniqueID();
        uniqueID.setType("28");
        uniqueID.setID(dtOrderChannelsEntity.getAccessKey());

        HotelReservations hotelReservations = new HotelReservations();
        hotelReservations.setLastModifyDateTime(DateUtils.format(DateUtils.addDateSeconds(new Date(),-30),"yyyy-MM-dd'T'HH:mm:ss.sssssss+08:00"));
        hotelReservations.setEndModifyDateTime(DateUtils.format(DateUtils.addDateSeconds(new Date(),0),"yyyy-MM-dd'T'HH:mm:ss.sssssss+08:00"));
        List<UniqueID> uniqueIDS = Lists.newArrayList();
        uniqueIDS.add(uniqueID);
        hotelReservations.setUniqueID(uniqueIDS);

        CtripMonitor ctripMonitor = new CtripMonitor();
        ctripMonitor.getHotelReservations().add(hotelReservations);
        ctripMonitor.setTimeStamp(DateUtils.format(new Date(),"yyyy-MM-dd'T'HH:mm:ss.sssssss"));
        ctripMonitor.setVersion(1);
        ctripMonitor.setPrimaryLangID("zh-cn");
        ctripDtInfo.setJsonData(JSONObject.toJSONString(ctripMonitor));
//        System.out.println("携程：检测订单状态接口，请求报文："+ctripDtInfo.getJsonData());
//        log.info("携程：检测订单状态接口，请求报文：{}",ctripDtInfo.getJsonData());
        String moniResult = "";
        try {
            moniResult = CtripClient.excuteReq(ctripDtInfo);
            if (moniResult.contains("INVALID_TOKEN") || moniResult.contains("232")) {
                // 睡眠2秒后在执行
                Thread.sleep(3000);
                monitOrdStatusAsyncTask(dtOrderChannelsEntity);
                return;
            }
        }catch (Exception ex) {
            log.error("携程：检测订单状态接口调用失败,错误信息：{}", ex.toString());
            return;
        }
        System.out.println("携程：检测订单状态返回结果信息："+moniResult);
//        log.info("携程：检测订单状态返回结果信息：{}",moniResult);
        CtripMonitorResponse monitorResponse = JSONObject.parseObject(moniResult,CtripMonitorResponse.class);
        List<RHotelReservations> rHotelReservations = monitorResponse.getHotelReservations();
        if (rHotelReservations==null){
            return;
        }
        log.info("监测到"+rHotelReservations.size()+"条订单状态");
        for (RHotelReservations rhs : rHotelReservations){
            List<HotelReservationIDs> hotelReservationIDs = rhs.getResGlobalInfo().getHotelReservationIDs();
            String resID_type = "";
            String buyOrdId = "";
            String oriBuyOrdId = "";
            if(hotelReservationIDs.size() == 1){
                buyOrdId = hotelReservationIDs.get(0).getResID_Value();
            }else if(hotelReservationIDs.size() > 1) {//订单号发生了变化
                for (HotelReservationIDs rid : hotelReservationIDs) {
                    if (StringUtils.equals(resID_type, "501")) {
                        oriBuyOrdId = rid.getResID_Value();
                    } else if (StringUtils.equals(resID_type, "507") || StringUtils.equals(resID_type, "509")) {
                        buyOrdId = rid.getResID_Value();
                    }
                }
            }
            //获取订单状态
            CtripDetail ctripDetail = new CtripDetail();
            UniqueID uniqueID2 = new UniqueID();
            uniqueID2.setType("501");
            uniqueID2.setID(buyOrdId);
            List<UniqueID> uLst = Lists.newArrayList();
            uLst.add(uniqueID2);
            ctripDetail.setUniqueID(uLst);
            ctripDtInfo.setICODE(CtripInterface.Detail.getValue());
            ctripDtInfo.setJsonData(JSONObject.toJSONString(ctripDetail));
            String detailResult = "";
            try{
                detailResult = CtripClient.excuteReq(ctripDtInfo);
                if (detailResult.contains("INVALID_TOKEN") || detailResult.contains("232")) {
                    // 睡眠2秒后在执行
                    Thread.sleep(2000);
                    detailResult = CtripClient.excuteReq(ctripDtInfo);
                    return;
                }
            }catch (Exception ex){
                log.error("订单检测，获取指定订单信息失败，订单号：{}，错误信息{}",buyOrdId,ex.toString());
                Map<String,Object> params = new HashMap<>();
                params.put("orderId",buyOrdId);
                params.put("buyStatus", Constant.LocalOrdBuyStatus.Purchfailure.getValue());
                //订单更改为手动订单
                params.put("orderType",0);
                params.put("resultDesc", "携程获取订单状态异常");
                deliGoodsService.updateOrderStatus(params);
            }

            JSONObject detailObject = JSONObject.parseObject(detailResult);
            if(StringUtils.equals(detailObject.getJSONObject("ResponseStatus").get("Ack").toString().toLowerCase(),"success")){
               String orderStatus = detailObject.getJSONArray("ReservationsList").getJSONObject(0).getString("OrderStatus").toLowerCase();
               if(StringUtils.equals(orderStatus,"confirm")){
                   //发货
                   if(StringUtils.isNotBlank(oriBuyOrdId)){//订单号发生改变
                       deliGoodsService.deliGood(Long.valueOf(oriBuyOrdId), Constant.OptType.Confirm,buyOrdId);
                   }else {
                       deliGoodsService.deliGood(Long.valueOf(buyOrdId), Constant.OptType.Confirm,buyOrdId);
                   }

               }else if(StringUtils.equals(orderStatus,"noroom")){
                    //发货
                   Map<String,Object> params = new HashMap<>();
                   params.put("orderId",buyOrdId);
                   if(StringUtils.isNotBlank(oriBuyOrdId)) {//订单号发生改变
                       params.put("orderId",buyOrdId);
                       params.put("newOrderId",buyOrdId);
                   }
                   params.put("buyStatus", Constant.LocalOrdBuyStatus.Purchfailure.getValue());
                   params.put("resultDesc", "采购失败：满房");
                   //订单更改为手动订单
                   params.put("orderType",0);
                   deliGoodsService.updateOrderStatus(params);

//                   deliGoodsService.deliGood(Long.valueOf(buyOrdId), Constant.OptType.NoRoom,"");
               }
            }
        }
    }
}
